package com.sduept.nwld.dataserver.controller.dataview;

import com.sduept.bigdata.document.core.CommonDocumentProperties;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.extend.WaveRatio;
import com.sduept.cim.model.wires.ACLineSegment;
import com.sduept.core.dao.SuperDAO;
import com.sduept.generator.ObjectId;
import com.sduept.nwld.dataserver.dto.LineparamDTO;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.dataserver.manager.cim.LineparamDTOManager;
import com.sduept.nwld.dataserver.util.CimUtils;
import com.sduept.nwld.dataserver.util.ExicelParseUtil;
import lombok.extern.slf4j.Slf4j;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

//import com.sduept.nwld.dataserver.model.edata.cim.bx.WaveRatio;
@Slf4j
@Named
@ViewScoped
public class AclinesegmentController extends AbstractController {
	private static final long serialVersionUID = -7321470726893838446L;
	@Autowired
	private CommonDocumentProperties pros;
	@Autowired
	private CimManager cimManger;
	@Autowired
	private LineparamDTOManager lineParamManager;
	@Autowired
	private SuperDAO dao;
	private List<ACLineSegment> aCLineSegments = new ArrayList<>();
	private List<LineparamDTO> lineparams = new ArrayList<>();
	private static int TabNum = 0;
	private String aCLineSegmentName;
	private String lineparamName;
	private String lineparamBus;
	private String lineparamSubStation;
	private String errLog;
	private List<WaveRatio> waveRatios = new ArrayList<>();
	private ACLineSegment selectACLineSegment = new ACLineSegment();
	private ACLineSegment aCLineSegment = new ACLineSegment();

	private String lineparamInfo;
	private String voltageInfo;
	private List<String> voltages;
	private String selectVoltage = "0";

	@PostConstruct
	public void init() {
		waveRatios = dao.findAll(WaveRatio.class);
		voltages = cimManger.findAclineStandVolLevelsStr();
		getACLineSegmentByVoltagelevel();
		lineparamsNotMatched();
        reset();
	}

	private void reset() {
		lineparamName = null;
		lineparamBus = null;
	    lineparamSubStation = null;
	    selectVoltage = "0";
	}

	private void voltageInfo() {
		if (selectVoltage.equals("0")) {
			voltageInfo = "请选择要查看的电压等级";
			return;
		}
		Long countAll = cimManger.countACLineByCondition(Float.parseFloat(selectVoltage));
		Long countNotMatch = dao.count("t_cim_aclinesegment", "*",
				" where id not in (select ems_id from t_imp_lineparams where ems_id is not null ) and standVoltagelevel ="
						+ selectVoltage);
		Long countMatched = dao.count("t_cim_aclinesegment", "*",
				" where id  in (select ems_id from t_imp_lineparams where ems_id is not null ) and standVoltagelevel ="
						+ selectVoltage);
		voltageInfo = selectVoltage + "kV线路共：" + countAll + "条,匹配上线路：" + countMatched + "条,未匹配：" + countNotMatch + "条";
	}

	private void lineparamInfo() {
		long lineparamcount = dao.count(LineparamDTO.class);
		long lineparamMathedCount = dao.count("t_imp_lineparams", "*",
				" where ems_id in (select id from t_cim_aclinesegment where standVoltagelevel="
						+ selectVoltage + " )");
		long lineparamNotMathedCount = dao.count("t_imp_lineparams", "*", "where ems_id is null");
		lineparamInfo = "变比总条数：" + lineparamcount + "条，未匹配线路共：" + lineparamNotMathedCount + "条";
		if (!selectVoltage.equals("0")) {
			lineparamInfo += "，其中已匹配" + selectVoltage + "Kv线路：" + lineparamMathedCount + "条";
		}
	}

	public void handleWaveFileUpload(FileUploadEvent event) {
		UploadedFile file = event.getFile();
		String houzhuiming = file.getFileName().substring(file.getFileName().lastIndexOf("."));
		String id = ObjectId.get().toString();
		String dirFileName = id + houzhuiming;
		String path = pros.getDocumentPath() + dirFileName;
		try {
			FileOutputStream fos = new FileOutputStream(path);
			fos.write(file.getContents());
			fos.close();
		} catch (IOException ee) {
			ee.printStackTrace();
			addErrorMessage("文件上传失败");
		}
		try {
			if (TabNum == 0) {
				importACLineSegmentFromFile(path, houzhuiming);
			} else {
				importLineparamsFromFile(path, houzhuiming);
			}
		} finally {
			File deleteFile = new File(path);
			if (deleteFile != null && deleteFile.isFile())
				deleteFile.delete();
			TabNum = 0;
		}

	}

	public void onRowSelect(SelectEvent event) {
		selectACLineSegment = (ACLineSegment) event.getObject();
	}

	public void searchACLineSegments() {
		aCLineSegments = cimManger.getAcLineSegmentByNameAndLength(aCLineSegmentName,Float.parseFloat(selectVoltage));
	}

	public void serchLineparams() {
		lineparams = lineParamManager.getLineparamByNameAndBusAndSubStation(lineparamName, lineparamBus,
				lineparamSubStation,Float.parseFloat(selectVoltage));
	}

	public void fileUpload() {
		TabNum = 1;
	}

	/**
	 * ACLineSegment 上传
	 * 
	 * @param path
	 * @param houzhuiming
	 * @throws Throwable
	 */
	private void importACLineSegmentFromFile(String path, String houzhuiming) {
		ExicelParseUtil exicelParseUtil = new ExicelParseUtil();
		List<List<Object>> lo = null;
		if (".xlsx".equals(houzhuiming)) {
			lo = exicelParseUtil.getFirstRowInfoOfXLSX(path, 1, 0);
		} else if (".xls".equals(houzhuiming)) {
			lo = exicelParseUtil.getFirstRowInfoOfXLS(path, 1, 0);
		}

		if (lo == null) {
			addErrorMessage("文件解析失败，请检查！");
			return;
		}
		List<ACLineSegment> la = cimManger.findAllAcLineSegement();
		StringBuffer buffer = new StringBuffer();
		for (List<Object> list : lo) {

			String name;
			Double length;
			Double r1;
			Double x1;
			Double r0;
			Double x0;
			try {
				name = list.get(0).toString();
				length = new Double(list.get(1).toString());
				r1 = new Double(list.get(2).toString());
				x1 = new Double(list.get(3).toString());
				r0 = new Double(list.get(4).toString());
				x0 = new Double(list.get(5).toString());
			} catch (Exception e) {
				addErrorMessage("文件解析失败，请检查格式！");
				return;
			}

			List<ACLineSegment> aCLineSegments = cimManger.getAcLineSegmentsByName(name);
			if (aCLineSegments.size() == 0) {
				for (ACLineSegment ac : la) {
					if (CimUtils.lineNameMatching(name, ac.getName())) {
						ac.setLength(length);
						ac.setR0(r0);
						ac.setR1(r1);
						ac.setX0(x0);
						ac.setX1(x1);
						cimManger.createOrUpdate(ac,ACLineSegment.class);
						break;
					} else if (ac.equals(la.get(la.size() - 1))) {
						buffer.append("\n不能匹配线路：" + name);
					}
				}
			} else if (aCLineSegments.size() == 1) {
				ACLineSegment ac = aCLineSegments.get(0);
				ac.setLength(length);
				ac.setR0(r0);
				ac.setR1(r1);
				ac.setX0(x0);
				ac.setX1(x1);
				cimManger.createOrUpdate(ac,ACLineSegment.class);
			} else {
				buffer.append("\n匹配到多个相同名字线路：" + name + "==数据库：=" + aCLineSegments.get(0).getName() + "==size=="
						+ aCLineSegments.size());
			}
		}
		errLog = buffer.toString();
		// addSuccessMessage("文件解析成功");
		aCLineSegments = cimManger.getAcLineSegmentsBystandVoltagelevel500();
	}

	/**
	 * Lineparams 上传
	 * 
	 * @param path
	 * @param houzhuiming
	 * @throws Throwable
	 */
	private void importLineparamsFromFile(String path, String houzhuiming) {
		ExicelParseUtil exicelParseUtil = new ExicelParseUtil();
		List<List<Object>> lo = null;
		StringBuffer buffer = new StringBuffer();
		if (".xlsx".equals(houzhuiming)) {
			lo = exicelParseUtil.getFirstRowInfoOfXLSX(path, 1, 0);
		}
		if (".xls".equals(houzhuiming)) {
			lo = exicelParseUtil.getFirstRowInfoOfXLS(path, 1, 0);
		}
		if (lo == null) {
			addErrorMessage("文件解析失败，请检查！");
			buffer.append("文件解析失败，请检查！");
			return;
		}
		// 变比字典表 pT /cT
		Set<Float> ctSet = new HashSet<>();
		Set<Float> ptSet = new HashSet<>();
		List<ACLineSegment> la = cimManger.getAcLineSegmentsBystandVoltagelevel500();
		List<Substation> stations = cimManger.listStationsByVoltageLevel(500,null);
		List<LineparamDTO> tempParams = new ArrayList<>();
		for (List<Object> list : lo) {
			String name = list.get(0).toString();
			String substation = list.get(2).toString();
			for (ACLineSegment ac : la) {
				if (CimUtils.lineNameMatching(name, ac.getName(), false)) {
					// 查找变电站
					Substation s = null;
					for (Substation tempStation : stations) {
						if (CimUtils.stationNameMatching(substation, tempStation.getName(), true)) {
							s = tempStation;
							break;
						}
					}
					// 找不到记录 执行下一条记录
					if (null == s) {
						log.info(name + "-" + substation + "匹配失败！");
						continue;
					}
					LineparamDTO dto = new LineparamDTO();
					try {
						String ta = list.get(3).toString();
						String tv = list.get(4).toString();
						Integer ta_p = new Integer(ta.split("/")[0]);
						Integer ta_s = new Integer(ta.split("/")[1]);
						Integer tv_p = new Integer(tv.split("/")[0]) * 1000;
						Integer tv_s = (int) (new Double(tv.split("/")[1]) * 1000);
						dto.setName(ac.getName());
						dto.setSubstation_id(s.getId());
						dto.setSubstation(s.getName());
						dto.setEms_id(ac.getId());
						dto.setTA(ta);
						dto.setTV(tv);
						dto.setTA_P(ta_p);
						dto.setTA_S(ta_s);
						dto.setTV_P(tv_p);
						dto.setTV_S(tv_s);
						dto.setNormal_vl((int)ac.getStandVoltagelevel());
						dto.setBus(list.get(2).toString());
					} catch (NumberFormatException e) {
						addErrorMessage("文件解析失败，请检查格式！");
						buffer.append(e.toString());
						break;
					}
					List<LineparamDTO> params = lineParamManager.listLineparamDTOsByNameAndStationName(dto.getName(), dto.getSubstation());
					if (params.size() == 0) {
						//新增数据
						dto.setId(ObjectId.get().toString());
						ctSet.add((float) dto.getTA_P() / (float) dto.getTA_S());
						ptSet.add((float) dto.getTV_P() / (float) dto.getTV_S());
						tempParams.add(dto);

					} else if (params.size() == 1) {
						//更新数据
						LineparamDTO param = params.get(0);
						param.setName(dto.getName());
						param.setSubstation_id(dto.getSubstation_id());
						param.setSubstation(dto.getSubstation());
						param.setEms_id(dto.getEms_id());
						param.setTA(dto.getTA());
						param.setTV(dto.getTV());
						param.setTA_P(dto.getTA_P());
						param.setTA_S(dto.getTV_S());
						param.setTV_P(dto.getTV_P());
						param.setTV_S(dto.getTV_S());
						param.setNormal_vl(dto.getNormal_vl());
						param.setBus(dto.getBus());
						ctSet.add((float) dto.getTA_P() / (float) dto.getTA_S());
						ptSet.add((float) dto.getTV_P() / (float) dto.getTV_S());
						lineParamManager.updateLineparam(dto);
					} 
					break;
				} 
			}
		}
		try {
			dao.persistentBatch(LineparamDTO.class, tempParams);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		errLog = buffer.toString();
		addSuccessMessage("文件解析成功");
		// ctSet
		for (Float f : ctSet) {
//			List<WaveRatio> lw = dao.findByCondition("ps = " + f + " and rtype = 'CT'", WaveRatio.class);
			List<WaveRatio> lw = dao.findByCondition(WaveRatio.class, "rtype = 'CT' and ps = ?", f);
			if (f != 1 && lw.size() == 0) {
				WaveRatio ptRatio = new WaveRatio();
				ptRatio.setRtype("CT");
				ptRatio.setPs(f);
				dao.create(ptRatio, WaveRatio.class);
			}
		}
		// ptSet
		for (Float f : ptSet) {
//			List<WaveRatio> lw = dao.findByCondition("ps = " + f + " and rtype = 'PT'", WaveRatio.class);
			List<WaveRatio> lw = dao.findByCondition(WaveRatio.class, "rtype = 'CT' and ps = ?", f);
			if (f != 1 && lw.size() == 0) {
				WaveRatio ptRatio = new WaveRatio();
				ptRatio.setRtype("PT");
				ptRatio.setPs(f);
				dao.create(ptRatio, WaveRatio.class);
			}
		}
		lineparams = lineParamManager.findAllLinerparams();
		waveRatios = dao.findAll(WaveRatio.class);
	}

	public void preACLineSegment() {
		aCLineSegment = new ACLineSegment();
	}

	public void editACLineSegment() {
		aCLineSegment = selectACLineSegment;
	}

	public void saveACLineSegment() {
		ACLineSegment acl = dao.createOrUpdate(aCLineSegment, ACLineSegment.class);
		if (aCLineSegment.getId() != null) {
			aCLineSegments.set(aCLineSegments.indexOf(selectACLineSegment), acl);
		} else {
			aCLineSegments.add(acl);

		}
		addSuccessMessage("保存成功");
	}

	public void deleteACLineSegment() {
		dao.delete(selectACLineSegment.getId(), ACLineSegment.class);
		aCLineSegments.remove(selectACLineSegment);
		addSuccessMessage("删除成功");
		selectACLineSegment = new ACLineSegment();
	}

	private String subString(String s) {

		if (s.contains("变")) {
			s = s.substring(0, s.indexOf("变"));
		}
		if (s.contains("站")) {
			s = s.substring(0, s.indexOf("站"));
		}
		if (s.contains("线")) {
			s = s.substring(0, s.indexOf("线"));
		}
		return s;
	}

	public void getNotMatch() {
		@SuppressWarnings("unchecked")
		List<String> list = (List<String>) dao.nativeQuery(
				"select id from t_cim_aclinesegment where id not in (select ems_id from t_imp_lineparams where ems_id is not null ) and standVoltagelevel ="
						+ selectVoltage);
		aCLineSegments.clear();
		for (String s : list) {
			aCLineSegments.add(dao.findById(s, ACLineSegment.class));
		}
	}

	public void getMatched() {
		@SuppressWarnings("unchecked")
		List<String> list = (List<String>) dao.nativeQuery(
				"select id from t_cim_aclinesegment where id in (select ems_id from t_imp_lineparams where ems_id is not null ) and standVoltagelevel ="
						+ selectVoltage);
		aCLineSegments.clear();
		for (String s : list) {
			aCLineSegments.add(dao.findById(s, ACLineSegment.class));
		}
	}

	public void getACLineSegmentByVoltagelevel() {
		aCLineSegments = cimManger.getAcLineSegmentsByStandVoltagelevel(Float.parseFloat(selectVoltage));
		voltageInfo();
	}

	public void getlineparamsByVoltagelevel() {
		lineparams = lineParamManager.getLineparamByCondition(
				" ems_id in (select a.id from ACLineSegment a where a.standVoltagelevel = "
						+ selectVoltage + " )");
		lineparamInfo();
	}

	public void lineparamsNotMatched() {
		lineparams = lineParamManager.getLineparamByCondition(" ems_id is null");
		lineparamInfo();
	}

	public List<ACLineSegment> getaCLineSegments() {
		return aCLineSegments;
	}

	public void setaCLineSegments(List<ACLineSegment> aCLineSegments) {
		this.aCLineSegments = aCLineSegments;
	}

	public List<LineparamDTO> getLineparams() {
		return lineparams;
	}

	public void setLineparams(List<LineparamDTO> lineparams) {
		this.lineparams = lineparams;
	}

	public String getaCLineSegmentName() {
		return aCLineSegmentName;
	}

	public void setaCLineSegmentName(String aCLineSegmentName) {
		this.aCLineSegmentName = aCLineSegmentName;
	}

	public String getLineparamName() {
		return lineparamName;
	}

	public void setLineparamName(String lineparamName) {
		this.lineparamName = lineparamName;
	}

	public String getLineparamBus() {
		return lineparamBus;
	}

	public void setLineparamBus(String lineparamBus) {
		this.lineparamBus = lineparamBus;
	}

	public String getLineparamSubStation() {
		return lineparamSubStation;
	}

	public void setLineparamSubStation(String lineparamSubStation) {
		this.lineparamSubStation = lineparamSubStation;
	}

	public String getErrLog() {
		return errLog;
	}

	public void setErrLog(String errLog) {
		this.errLog = errLog;
	}

	public List<WaveRatio> getWaveRatios() {
		return waveRatios;
	}

	public void setWaveRatios(List<WaveRatio> waveRatios) {
		this.waveRatios = waveRatios;
	}

	public ACLineSegment getSelectACLineSegment() {
		return selectACLineSegment;
	}

	public void setSelectACLineSegment(ACLineSegment selectACLineSegment) {
		this.selectACLineSegment = selectACLineSegment;
	}

	public ACLineSegment getaCLineSegment() {
		return aCLineSegment;
	}

	public void setaCLineSegment(ACLineSegment aCLineSegment) {
		this.aCLineSegment = aCLineSegment;
	}

	public String getLineparamInfo() {
		return lineparamInfo;
	}

	public void setLineparamInfo(String lineparamInfo) {
		this.lineparamInfo = lineparamInfo;
	}

	public List<String> getVoltages() {
		return voltages;
	}

	public void setVoltages(List<String> voltages) {
		this.voltages = voltages;
	}

	public String getSelectVoltage() {
		return selectVoltage;
	}

	public void setSelectVoltage(String selectVoltage) {
		this.selectVoltage = selectVoltage;
	}

	public String getVoltageInfo() {
		return voltageInfo;
	}

	public void setVoltageInfo(String voltageInfo) {
		this.voltageInfo = voltageInfo;
	}
}
